/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package deatax.display.gui;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.LayoutManager2;
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;

/**
 *
 * @author nrechten
 */
public class CPSLayout implements LayoutManager2 {

    public static CPSConfig DEFAULT_CONFIG = new CPSConfig();

    private Dimension minBounds;
    private List<LayoutComponent> components = new ArrayList<LayoutComponent>();


    public void addLayoutComponent(String name, Component comp) {
        components.add(new LayoutComponent(comp,DEFAULT_CONFIG));
    }

    public void removeLayoutComponent(Component comp) {
        components.remove(comp);
    }

    public Dimension preferredLayoutSize(Container parent) {
        return minimumLayoutSize(parent);
    }

    public Dimension minimumLayoutSize(Container parent) {
        if(minBounds == null){
            CalcMinBounds();
        }
        return minBounds;
    }


    public void CalcMinBounds(){
        int min_w = 0;
        int min_h = 0;
        for (LayoutComponent component : components) {
            if(component.config.useComponentMinMax){
                Dimension temp = component.comp.getMaximumSize();
                component.config.w_max = temp.width;
                component.config.h_max = temp.height;
                temp = component.comp.getMinimumSize();
                component.config.w_min = temp.width;
                component.config.h_min = temp.height;
            }
            Rectangle r = component.config.calculateBounds(0,0);
//            System.out.println(r);
            min_w = Math.max(min_w,r.width + Math.max(0,r.x));
            min_h = Math.max(min_h,r.height + Math.max(0,r.y));
        }
        minBounds = new Dimension(min_w,min_h);
//        System.out.println(minBounds);

    }

    public void layoutContainer(Container parent) {

        int width = parent.getWidth();
        int height = parent.getHeight();

        for (LayoutComponent component : components) {
            if(component.config.useComponentMinMax){
                Dimension temp = component.comp.getMaximumSize();
                component.config.w_max = temp.width;
                component.config.h_max = temp.height;
                temp = component.comp.getMinimumSize();
                component.config.w_min = temp.width;
                component.config.h_min = temp.height;
            }

            component.comp.setBounds(component.config.calculateBounds(width, height));
        }
    }

    public void addLayoutComponent(Component comp, Object constraints) {
        if( constraints instanceof CPSConfig){
            components.add(new LayoutComponent(comp,(CPSConfig)constraints));
        } else {
            components.add(new LayoutComponent(comp,DEFAULT_CONFIG));
        }
    }

    public Dimension maximumLayoutSize(Container target) {
        return target.getMaximumSize();
    }

    public float getLayoutAlignmentX(Container target) {
        return 0.5f;
    }

    public float getLayoutAlignmentY(Container target) {
        return 0.5f;
    }

    public void invalidateLayout(Container target) {
        CalcMinBounds();
    }

    private class LayoutComponent{

        Component comp;
        CPSConfig config;

        public LayoutComponent(Component c, CPSConfig config){
            this.comp = c;
            this.config = config;
        }

        @Override
        public boolean equals(Object obj) {
            if(obj instanceof LayoutComponent){
                return this.comp == ((LayoutComponent)obj).comp;
            }
            return super.equals(obj);
        }

        @Override
        public int hashCode() {
            int hash = 5;
            hash = 43 * hash + (this.comp != null ? this.comp.hashCode() : 0);
            return hash;
        }
    }


//    public static void main(String[] args) {
//
//        JPanel foo = new JPanel();
//        foo.setLayout(new CPSLayout());
//
//        JPanel bar = new JPanel();
//        bar.setBackground(Color.red);
//
//        foo.add(bar, new CPSConfig(CPSConfig.RIGHT, CPSConfig.BOTTOM, 10, 10, 100,100));
//
//        bar = new JPanel();
//        bar.setBackground(Color.green);
//        foo.add(bar, new CPSConfig(CPSConfig.LEFT, CPSConfig.BOTTOM, 10, 10, 100,100));
//
//        bar = new JPanel();
//        bar.setBackground(Color.yellow);
//        foo.add(bar, new CPSConfig(CPSConfig.LEFT, CPSConfig.TOP, 0f,0f, 10, 10, 1f, 0f, -20, 100));
//
//        bar = new JPanel();
//        bar.setBackground(Color.BLUE);
//        foo.add(bar, new CPSConfig(CPSConfig.CENTER, CPSConfig.CENTER, 0, 0, 100,10));
//
//        bar = new JPanel();
//        bar.setBackground(Color.BLUE);
//        foo.add(bar, new CPSConfig(CPSConfig.CENTER, CPSConfig.CENTER, 0f, 0f, 0, 20, 0.3f, 0f, 0, 10));
//
//        bar = new JPanel();
//
//        bar.add(new JPanel());
//
//        bar.setBackground(Color.BLUE);
//        foo.add(bar, new CPSConfig(CPSConfig.CENTER, CPSConfig.CENTER, 0f, 0f, 0, 40, 0.5f, 0f, 0, 10));
//
//
//        openJFrame(foo);
//    }


    public static JFrame openJFrame(Component c){
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(c, BorderLayout.CENTER);

        f.setVisible(true);
        f.pack();
        f.setLocationRelativeTo(null);
        return f;
    }
}
